﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using Meridian;
using MeridianZ.Helpers;
using VkApi;

namespace MeridianZ.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection<VkAudio> myAudio;
        public ObservableCollection<VkAudio> MyAudio
        {
            get { return myAudio; }
            set
            {
                if (myAudio == value)
                    return;
                myAudio = value;
                RaisePropertyChanged("MyAudio");
            }
        }

        private ObservableCollection<VkAudio> searchResults;
        public ObservableCollection<VkAudio> SearchResults
        {
            get { return searchResults; }
            set
            {
                if (searchResults == value)
                    return;
                searchResults = value;
                RaisePropertyChanged("SearchResults");
            }
        }

        private bool isLoading;
        public bool IsLoading
        {
            get { return isLoading; }
            set
            {
                if (isLoading == value)
                    return;
                isLoading = value;
                RaisePropertyChanged("IsLoading");
            }
        }

        private bool isLoaded;
        public bool IsLoaded
        {
            get { return isLoaded; }
            set
            {
                if (isLoaded == value)
                    return;
                isLoaded = value;
                RaisePropertyChanged("IsLoaded");
            }
        }

        private Uri userPicture;
        public Uri UserPicture
        {
            get { return userPicture; }
            set
            {
                if (userPicture == value)
                    return;
                userPicture = value;
                RaisePropertyChanged("UserPicture");
            }
        }

        private string userName;
        public string UserName
        {
            get { return userName; }
            set
            {
                if (userName == value)
                    return;
                userName = value;
                RaisePropertyChanged("UserName");
            }
        }

        private string userLastName;
        public string UserLastName
        {
            get { return userLastName; }
            set
            {
                if (userLastName == value)
                    return;
                userLastName = value;
                RaisePropertyChanged("UserLastName");
            }
        }

        public MainViewModel()
        {
            userPicture = new Uri("/Resources/Images/userpic_default.png", UriKind.Relative);
            UserName = Properties.Resources.SignIn;
        }

        public void Login()
        {
            if (!Global.IsAuthorized)
            {
                IsLoading = true;
                UserName = Properties.Resources.Authorization;
                ThreadHelper.InvokeAsync(() => AuthHelper.Authorize(AuthorizeCallback));
            }
            else
                Load(App.Settings.FirstLoadItemsCount);
        }

        void AuthorizeCallback()
        {
            if (!App.Vkontakte.AuthResult.IsSuccess)
            {
                MessageBox.Show(App.Vkontakte.AuthResult.Error);
                return;
            }
            Load(App.Settings.FirstLoadItemsCount);
        }

        public void Load(int count)
        {
            IsLoading = true;
            ThreadHelper.InvokeAsync(() =>
                                         {
                                             var profile = App.Vkontakte.GetUserProfile();

                                             if (profile == null)
                                             {
                                                 Global.IsAuthorized = false;
                                                 if (App.Vkontakte.LastError != null && App.Vkontakte.LastError.ErrorCode == 5)
                                                 {
                                                     Login();
                                                     Load(count);
                                                 }
                                                 return;
                                             }

                                             GetUserProfileCallback(profile);

                                             var audio = App.Vkontakte.GetAudio(count);

                                             GetAudioCallback(audio);
                                         });
        }

        public void LoadMore(int count)
        {
            if (myAudio == null)
                return;
            if (IsLoading)
                return;
            IsLoading = true;
            ThreadHelper.InvokeAsync(() =>
                                         {
                                             var audio = App.Vkontakte.GetAudio(count, myAudio.Count);
                                             GetMoreAudioCallback(audio);
                                         });

        }

        public void Search(string query, int count)
        {
            IsLoading = true;
            ThreadHelper.InvokeAsync(() =>
                                         {
                                             var audio = App.Vkontakte.SearchAudio(query, count);
                                             SearchCallback(audio);
                                         });
        }

        public void SearchMore(string query, int count)
        {
            if (searchResults == null)
                return;
            if (IsLoading)
                return;
            IsLoading = true;
            ThreadHelper.InvokeAsync(() =>
            {
                var audio = App.Vkontakte.SearchAudio(query, count, searchResults.Count);
                SearchMoreCallback(audio);
            });
        }

        public void AddAudio(VkAudio audio)
        {
            ThreadHelper.InvokeAsync(() =>
            {
                App.Vkontakte.AddAudio(audio.Id.ToString(), audio.OwnerId.ToString());
                Load(myAudio.Count);
            });
        }

        public void DeleteAudio(VkAudio audio)
        {
            ThreadHelper.InvokeAsync(() =>
            {
                App.Vkontakte.DeleteAudio(audio.Id.ToString(), audio.OwnerId.ToString());
                Load(myAudio.Count);
            });
        }

        void GetUserProfileCallback(VkProfile profile)
        {
            IsLoading = false;
            UserName = profile.FirstName;
            UserLastName = profile.LastName;
            UserPicture = new Uri(profile.PhotoUrl);
        }

        void GetAudioCallback(List<VkAudio> audio)
        {
            IsLoading = false;
            IsLoaded = true;

            if (myAudio != null)
            {
                Application.Current.Dispatcher.Invoke((Action)(() => myAudio.Clear()));
            }
            MyAudio = new ObservableCollection<VkAudio>(audio);
        }

        void GetMoreAudioCallback(IEnumerable<VkAudio> audio)
        {
            Application.Current.Dispatcher.Invoke((Action)delegate
            {
                foreach (var vkAudio in audio)
                {
                    MyAudio.Add(vkAudio);
                }
            });
            IsLoading = false;
        }

        void SearchCallback(List<VkAudio> audio)
        {
            IsLoading = false;
            IsLoaded = true;

            if (audio == null)
                return;

            if (searchResults != null)
            {
                Application.Current.Dispatcher.Invoke((Action)(() => searchResults.Clear()));
            }
            SearchResults = new ObservableCollection<VkAudio>(audio);
        }

        void SearchMoreCallback(IEnumerable<VkAudio> audio)
        {
            IsLoading = false;

            Application.Current.Dispatcher.Invoke((Action)delegate
            {
                foreach (var vkAudio in audio)
                {
                    SearchResults.Add(vkAudio);
                }
            });
        }
    }
}
